package com.grs.demo.vr;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.res.Configuration;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Bundle;
import android.support.v4.util.SimpleArrayMap;
import android.util.Log;
import android.util.SparseArray;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.widget.TextView;
import android.widget.Toast;

import com.asha.vrlib.MDVRLibrary;
import com.asha.vrlib.model.MDHotspotBuilder;
import com.asha.vrlib.model.MDPosition;
import com.asha.vrlib.model.MDRay;
import com.asha.vrlib.model.MDViewBuilder;
import com.asha.vrlib.model.position.MDMutablePosition;
import com.asha.vrlib.plugins.MDAbsPlugin;
import com.asha.vrlib.plugins.MDWidgetPlugin;
import com.asha.vrlib.plugins.hotspot.IMDHotspot;
import com.asha.vrlib.plugins.hotspot.MDAbsHotspot;
import com.asha.vrlib.plugins.hotspot.MDAbsView;
import com.asha.vrlib.plugins.hotspot.MDSimpleHotspot;
import com.asha.vrlib.plugins.hotspot.MDView;
import com.asha.vrlib.texture.MD360BitmapTexture;
import com.grs.demo.R;
import com.squareup.picasso.Picasso;
import com.squareup.picasso.Target;

import java.io.FileNotFoundException;
import java.util.LinkedList;
import java.util.List;
import java.util.Locale;

import static com.squareup.picasso.MemoryPolicy.NO_CACHE;
import static com.squareup.picasso.MemoryPolicy.NO_STORE;

/**
 * using MD360Renderer
 * Created by hzqiujiadi on 16/1/22.
 * hzqiujiadi ashqalcn@gmail.com
 */
public abstract class MD360PlayerActivity extends Activity {

	private static final String TAG = "MD360PlayerActivity";

	private static final SparseArray<String> sDisplayMode = new SparseArray<>();
	private static final SparseArray<String> sInteractiveMode = new SparseArray<>();
	private static final SparseArray<String> sProjectionMode = new SparseArray<>();
	private static final SparseArray<String> sAntiDistortion = new SparseArray<>();

	static {
		//显示模式
		sDisplayMode.put(MDVRLibrary.DISPLAY_MODE_NORMAL, "正常");
		sDisplayMode.put(MDVRLibrary.DISPLAY_MODE_GLASS, "眼镜");
		//交互模式
		sInteractiveMode.put(MDVRLibrary.INTERACTIVE_MODE_MOTION, "自动");
		sInteractiveMode.put(MDVRLibrary.INTERACTIVE_MODE_TOUCH, "手动");
		sInteractiveMode.put(MDVRLibrary.INTERACTIVE_MODE_MOTION_WITH_TOUCH, "自动+手动");
		sInteractiveMode.put(MDVRLibrary.INTERACTIVE_MODE_CARDBORAD_MOTION, "纸板+自动");
		sInteractiveMode.put(MDVRLibrary.INTERACTIVE_MODE_CARDBORAD_MOTION_WITH_TOUCH, "纸板+自动+手动");
		//投射模式
		sProjectionMode.put(MDVRLibrary.PROJECTION_MODE_SPHERE, "球形");
		sProjectionMode.put(MDVRLibrary.PROJECTION_MODE_DOME180, "半球 180");
		sProjectionMode.put(MDVRLibrary.PROJECTION_MODE_DOME230, "半球 230");
		sProjectionMode.put(MDVRLibrary.PROJECTION_MODE_DOME180_UPPER, "半球 180 上层");
		sProjectionMode.put(MDVRLibrary.PROJECTION_MODE_DOME230_UPPER, "半球 230 上层");
		sProjectionMode.put(MDVRLibrary.PROJECTION_MODE_STEREO_SPHERE_HORIZONTAL, "立体球 水平");
		sProjectionMode.put(MDVRLibrary.PROJECTION_MODE_STEREO_SPHERE_VERTICAL, "立体球 垂直");
		sProjectionMode.put(MDVRLibrary.PROJECTION_MODE_PLANE_FIT, "平面 适应");
		sProjectionMode.put(MDVRLibrary.PROJECTION_MODE_PLANE_CROP, "平面 扩展");
		sProjectionMode.put(MDVRLibrary.PROJECTION_MODE_PLANE_FULL, "平面 填充");
		sProjectionMode.put(MDVRLibrary.PROJECTION_MODE_MULTI_FISH_EYE_HORIZONTAL, "多水平鱼眼");
		sProjectionMode.put(MDVRLibrary.PROJECTION_MODE_MULTI_FISH_EYE_VERTICAL, "多垂直鱼眼");
		sProjectionMode.put(CustomProjectionFactory.CUSTOM_PROJECTION_FISH_EYE_RADIUS_VERTICAL, "自定义多鱼眼");
		//反向呈现
		sAntiDistortion.put(1, "反向");
		sAntiDistortion.put(0, "不反向");
	}

	public static void startVideo(Context context, Uri uri) {
		start(context, uri, VideoPlayerActivity.class);
	}

	public static void startBitmap(Context context, Uri uri) {
		start(context, uri, BitmapPlayerActivity.class);
	}

	private static void start(Context context, Uri uri, Class<? extends Activity> clz) {
		Intent i = new Intent(context, clz);
		i.setData(uri);
		context.startActivity(i);
	}

	private MDVRLibrary mVRLibrary;

	// load resource from android drawable and remote url.
	private MDVRLibrary.IImageLoadProvider mImageLoadProvider = new ImageLoadProvider();

	// load resource from android drawable only.
	private MDVRLibrary.IImageLoadProvider mAndroidProvider = new AndroidProvider(this);

	private List<MDAbsPlugin> plugins = new LinkedList<>();
	//logo位置
	private MDPosition logoPosition = MDMutablePosition.newInstance().setY(-8.0f).setYaw(-90.0f);

	private MDPosition[] positions = new MDPosition[]{
			MDPosition.newInstance().setZ(-8.0f).setYaw(-45.0f),//视图-正中心
			MDPosition.newInstance().setZ(-18.0f).setYaw(15.0f).setAngleX(15),
			MDPosition.newInstance().setZ(-10.0f).setYaw(-10.0f).setAngleX(-15),
			MDPosition.newInstance().setZ(-10.0f).setYaw(30.0f).setAngleX(30),
			MDPosition.newInstance().setZ(-10.0f).setYaw(-30.0f).setAngleX(-30),
			MDPosition.newInstance().setZ(-5.0f).setYaw(30.0f).setAngleX(60),
			MDPosition.newInstance().setZ(-3.0f).setYaw(15.0f).setAngleX(-45),
			MDPosition.newInstance().setZ(-3.0f).setYaw(15.0f).setAngleX(-45).setAngleY(45),
			MDPosition.newInstance().setZ(-3.0f).setYaw(0.0f).setAngleX(90),
	};

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);

		// no title
		requestWindowFeature(Window.FEATURE_NO_TITLE);

		// full screen
		getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
				WindowManager.LayoutParams.FLAG_FULLSCREEN);

		// set content view
		setContentView(R.layout.activity_md_using_surface_view);

		// init VR Library
		mVRLibrary = createVRLibrary();

		final Activity activity = this;

		final List<View> hotspotPoints = new LinkedList<>();
		hotspotPoints.add(findViewById(R.id.hotspot_point1));
		hotspotPoints.add(findViewById(R.id.hotspot_point2));
		//显示模式
		SpinnerHelper.with(this)
				.setData(sDisplayMode)
				.setDefault(mVRLibrary.getDisplayMode())
				.setClickHandler(new SpinnerHelper.ClickHandler() {
					@Override
					public void onSpinnerClicked(int index, int key, String value) {
						mVRLibrary.switchDisplayMode(MD360PlayerActivity.this, key);
						int i = 0;
						int size = key == MDVRLibrary.DISPLAY_MODE_GLASS ? 2 : 1;
						for (View point : hotspotPoints) {
							point.setVisibility(i < size ? View.VISIBLE : View.GONE);
							i++;
						}
					}
				})
				.init(R.id.spinner_display);
		//交互模式
		SpinnerHelper.with(this)
				.setData(sInteractiveMode)
				.setDefault(mVRLibrary.getInteractiveMode())
				.setClickHandler(new SpinnerHelper.ClickHandler() {
					@Override
					public void onSpinnerClicked(int index, int key, String value) {
						mVRLibrary.switchInteractiveMode(MD360PlayerActivity.this, key);
					}
				})
				.init(R.id.spinner_interactive);
		//投射模式
		SpinnerHelper.with(this)
				.setData(sProjectionMode)
				.setDefault(mVRLibrary.getProjectionMode())
				.setClickHandler(new SpinnerHelper.ClickHandler() {
					@Override
					public void onSpinnerClicked(int index, int key, String value) {
						mVRLibrary.switchProjectionMode(MD360PlayerActivity.this, key);
					}
				})
				.init(R.id.spinner_projection);
		//反向呈现
		SpinnerHelper.with(this)
				.setData(sAntiDistortion)
				.setDefault(mVRLibrary.isAntiDistortionEnabled() ? 1 : 0)
				.setClickHandler(new SpinnerHelper.ClickHandler() {
					@Override
					public void onSpinnerClicked(int index, int key, String value) {
						mVRLibrary.setAntiDistortionEnabled(key != 0);
					}
				})
				.init(R.id.spinner_distortion);
		//添加插件-自定义组合图片
		findViewById(R.id.button_add_plugin).setOnClickListener(new View.OnClickListener() {
			@Override
			public void onClick(View v) {
//				final int index = (int) (Math.random() * 100) % positions.length;
				for (int index = 0; index < positions.length; index++) {
					MDPosition position = positions[index];
					MDHotspotBuilder builder = MDHotspotBuilder.create(mImageLoadProvider)
							.size(4f, 4f)
							.provider(0, activity, android.R.drawable.star_off)
							.provider(1, activity, android.R.drawable.star_on)
							.provider(10, activity, android.R.drawable.checkbox_off_background)
							.provider(11, activity, android.R.drawable.checkbox_on_background)
							.listenClick(new MDVRLibrary.ITouchPickListener() {
								@Override
								public void onHotspotHit(IMDHotspot hitHotspot, MDRay ray) {
									Log.e(TAG, "onHotspotHit: ray = "+ray.toString());
									Toast.makeText(MD360PlayerActivity.this, "click plugin"+hitHotspot.getTitle(), Toast.LENGTH_SHORT).show();
									if (hitHotspot instanceof MDWidgetPlugin) {
										MDWidgetPlugin widgetPlugin = (MDWidgetPlugin) hitHotspot;
										widgetPlugin.setChecked(!widgetPlugin.getChecked());
									}
								}
							})
							.title("star" + index)
							.position(position)
							.status(0, 1)
							.checkedStatus(10, 11);

					MDWidgetPlugin plugin = new MDWidgetPlugin(builder);

					plugins.add(plugin);
					getVRLibrary().addPlugin(plugin);
				}
//				Toast.makeText(MD360PlayerActivity.this, "add plugin position:" + position, Toast.LENGTH_SHORT).show();
			}
		});
		//添加logo
		findViewById(R.id.button_add_plugin_logo).setOnClickListener(new View.OnClickListener() {
			@Override
			public void onClick(View v) {
				MDHotspotBuilder builder = MDHotspotBuilder.create(mImageLoadProvider)
						.size(4f, 4f)
						.provider(activity, R.drawable.moredoo_logo)
						.title("logo")
						.position(logoPosition)
						.listenClick(new MDVRLibrary.ITouchPickListener() {
							@Override
							public void onHotspotHit(IMDHotspot hitHotspot, MDRay ray) {
								Toast.makeText(MD360PlayerActivity.this, "click logo", Toast.LENGTH_SHORT).show();
							}
						});
				MDAbsHotspot hotspot = new MDSimpleHotspot(builder);
				plugins.add(hotspot);
				getVRLibrary().addPlugin(hotspot);
				Toast.makeText(MD360PlayerActivity.this, "add plugin logo", Toast.LENGTH_SHORT).show();
			}
		});
		//移除上一个
		findViewById(R.id.button_remove_plugin).setOnClickListener(new View.OnClickListener() {
			@Override
			public void onClick(View v) {
				if (plugins.size() > 0) {
					MDAbsPlugin plugin = plugins.remove(plugins.size() - 1);
					getVRLibrary().removePlugin(plugin);
				}
			}
		});
		//移除所有
		findViewById(R.id.button_remove_plugins).setOnClickListener(new View.OnClickListener() {
			@Override
			public void onClick(View v) {
				plugins.clear();
				getVRLibrary().removePlugins();
			}
		});
		//添加 热点区
		findViewById(R.id.button_add_hotspot_front).setOnClickListener(new View.OnClickListener() {
			@Override
			public void onClick(View v) {
				MDHotspotBuilder builder = MDHotspotBuilder.create(mImageLoadProvider)
						.size(4f, 4f)
						.provider(activity, R.drawable.moredoo_logo)
						.title("front logo")
						.tag("tag-front")
						.position(MDPosition.newInstance().setZ(-12.0f).setY(-1.0f));
				MDAbsHotspot hotspot = new MDSimpleHotspot(builder);
				hotspot.rotateToCamera();
				plugins.add(hotspot);
				getVRLibrary().addPlugin(hotspot);
			}
		});
		//移动 热点区
		findViewById(R.id.button_rotate_to_camera_plugin).setOnClickListener(new View.OnClickListener() {
			@Override
			public void onClick(View v) {
				IMDHotspot hotspot = getVRLibrary().findHotspotByTag("tag-front");
				if (hotspot != null) {
					hotspot.rotateToCamera();
				}
			}
		});
		//添加view
		findViewById(R.id.button_add_md_view).setOnClickListener(new View.OnClickListener() {
			@Override
			public void onClick(View v) {
				TextView textView = new TextView(activity);
				textView.setBackgroundColor(0x55FF0000);
				textView.setText("Hello world.");

				MDViewBuilder builder = MDViewBuilder.create()
						.provider(textView, 400/*view width*/, 100/*view height*/)
						.size(4, 1)
						.position(MDPosition.newInstance().setZ(-12.0f))
						.title("md view")
						.tag("tag-md-text-view");

				MDAbsView mdView = new MDView(builder);
				plugins.add(mdView);
				getVRLibrary().addPlugin(mdView);
			}
		});
		//更新view
		findViewById(R.id.button_update_md_view).setOnClickListener(new View.OnClickListener() {
			@Override
			public void onClick(View v) {
				MDAbsView mdView = getVRLibrary().findViewByTag("tag-md-text-view");
				if (mdView != null) {
					TextView textView = mdView.castAttachedView(TextView.class);
					textView.setText("Cheer up!");
					textView.setBackgroundColor(0x8800FF00);
					mdView.invalidate();
				}
			}
		});
		//热点 位置
		final TextView hotspotText = (TextView) findViewById(R.id.hotspot_text);
		getVRLibrary().setEyePickChangedListener(new MDVRLibrary.IEyePickListener() {
			@Override
			public void onHotspotHit(IMDHotspot hotspot, long hitTimestamp) {
				String text = hotspot == null ? "nop" : String.format(Locale.CHINESE, "%s  %fs", hotspot.getTitle(), (System.currentTimeMillis() - hitTimestamp) / 1000.0f);
//				Log.e(TAG, "onHotspotHit:text= " + text);
				hotspotText.setText(text);

				if (System.currentTimeMillis() - hitTimestamp > 5000) {
					getVRLibrary().resetEyePick();
				}
			}
		});
	}

	abstract protected MDVRLibrary createVRLibrary();

	public MDVRLibrary getVRLibrary() {
		return mVRLibrary;
	}

	@Override
	protected void onResume() {
		super.onResume();
		mVRLibrary.onResume(this);
	}

	@Override
	protected void onPause() {
		super.onPause();
		mVRLibrary.onPause(this);
	}

	@Override
	protected void onDestroy() {
		super.onDestroy();
		mVRLibrary.onDestroy();
	}

	@Override
	public void onConfigurationChanged(Configuration newConfig) {
		super.onConfigurationChanged(newConfig);
		mVRLibrary.onOrientationChanged(this);
	}

	protected Uri getUri() {
		Intent i = getIntent();
		if (i == null || i.getData() == null) {
			return null;
		}
		return i.getData();
	}

	public void cancelBusy() {
		findViewById(R.id.progress).setVisibility(View.GONE);
	}

	public void busy() {
		findViewById(R.id.progress).setVisibility(View.VISIBLE);
	}

	// android impl
	private class AndroidProvider implements MDVRLibrary.IImageLoadProvider {

		Activity activity;

		public AndroidProvider(Activity activity) {
			this.activity = activity;
		}

		@Override
		public void onProvideBitmap(Uri uri, MD360BitmapTexture.Callback callback) {
			try {
				Bitmap bitmap = BitmapFactory.decodeStream(activity.getContentResolver().openInputStream(uri));
				callback.texture(bitmap);
			} catch (FileNotFoundException e) {
				e.printStackTrace();
			}

		}
	}

	// picasso impl
	private class ImageLoadProvider implements MDVRLibrary.IImageLoadProvider {

		private SimpleArrayMap<Uri, Target> targetMap = new SimpleArrayMap<>();

		@Override
		public void onProvideBitmap(final Uri uri, final MD360BitmapTexture.Callback callback) {

			final Target target = new Target() {

				@Override
				public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) {
					// texture
					callback.texture(bitmap);
					targetMap.remove(uri);
				}

				@Override
				public void onBitmapFailed(Drawable errorDrawable) {
					targetMap.remove(uri);
				}

				@Override
				public void onPrepareLoad(Drawable placeHolderDrawable) {

				}
			};
			targetMap.put(uri, target);
			Picasso.with(getApplicationContext()).load(uri).resize(callback.getMaxTextureSize(), callback.getMaxTextureSize()).onlyScaleDown().centerInside().memoryPolicy(NO_CACHE, NO_STORE).into(target);
		}
	}
}